﻿#region License

// Another free, open solution by folks who get it.
// Copyright © 2011 Business in Unison, Inc.
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#endregion

using System;
using System.Collections.Generic;
using System.Data;

namespace Patterns.Data
{
	/// <summary>
	/// 	Defines an interface for fluent repository providers.
	/// </summary>
	public interface IFluentCommand
	{
		/// <summary>
		/// 	Sets the repository command type.
		/// </summary>
		/// <param name = "type">The type.</param>
		/// <returns></returns>
		IFluentCommand OfType(CommandType type);

		/// <summary>
		/// 	Sets the repository command text.
		/// </summary>
		/// <param name = "text">The text.</param>
		/// <returns></returns>
		IFluentCommand WithText(string text);

		/// <summary>
		/// 	Adds the parameter to the repository command.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "name">The name.</param>
		/// <param name = "value">The value.</param>
		/// <returns></returns>
		IFluentCommand WithParameter<T>(string name, T value);

		/// <summary>
		/// 	Adds the parameter to the repository command.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "name">The name.</param>
		/// <param name = "value">The value.</param>
		/// <param name = "size">The size.</param>
		/// <returns></returns>
		IFluentCommand WithParameter<T>(string name, T value, int? size);

		/// <summary>
		/// 	Adds the parameter to the repository command.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "name">The name.</param>
		/// <param name = "value">The value.</param>
		/// <param name = "direction">The direction.</param>
		/// <returns></returns>
		IFluentCommand WithParameter<T>(string name, T value, ParameterDirection? direction);

		/// <summary>
		/// 	Adds the parameter to the repository command.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "name">The name.</param>
		/// <param name = "value">The value.</param>
		/// <param name = "size">The size.</param>
		/// <param name = "direction">The direction.</param>
		/// <returns></returns>
		IFluentCommand WithParameter<T>(string name, T value, int? size, ParameterDirection? direction);

		/// <summary>
		/// 	Runs the repository command as a non-query.
		/// </summary>
		/// <returns></returns>
		int AsNonQuery();

		/// <summary>
		/// 	Fills a data table with the results of the repository command.
		/// </summary>
		/// <returns></returns>
		DataTable AsTable();

		/// <summary>
		/// 	Fills a data set with the results of the repository command.
		/// </summary>
		/// <returns></returns>
		DataSet AsDataSet();

		/// <summary>
		/// 	Converts the results of the repository command into a set of instances
		/// 	of the specified type using the custom map.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <param name = "customMap">The custom map.</param>
		/// <returns></returns>
		IEnumerable<T> AsCustom<T>(Func<IDataRecord, T> customMap);

		/// <summary>
		/// 	Converts the results of the repository command into a set of instances
		/// 	of the specified type.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <returns></returns>
		IEnumerable<T> As<T>();

		/// <summary>
		/// 	Converts the first result of the repository command into an instance
		/// 	of the specified type.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <returns></returns>
		T AsSingle<T>();

		/// <summary>
		/// 	Converts the scalar result of the repository command into an instance
		/// 	of the specified type.
		/// </summary>
		/// <typeparam name = "T"></typeparam>
		/// <returns></returns>
		T AsScalar<T>();
	}
}